#include "CollisionManager.h"
#include <boost/foreach.hpp>

#define foreach BOOST_FOREACH

CollisionManager* CollisionManager::singleton = 0;

CollisionManager::CollisionManager() {}

CollisionManager::~CollisionManager() {}

CollisionManager* CollisionManager::getInstance()
{
	if (!singleton) {
		singleton = new CollisionManager();
	}
	return singleton;
}

void CollisionManager::dropInstance()
{
	if (singleton) {
		delete singleton;
		singleton = 0;
	}
}

void CollisionManager::Add(const b2ContactPoint* point)
{
	b2ContactPoint cp;
	cp.shape1 = point->shape1;
	cp.shape2 = point->shape2;
	cp.position = point->position;
	cp.normal = point->normal;
	cp.id = point->id;
	contactPoints[cp.id.key] = cp;
}

void CollisionManager::Persist(const b2ContactPoint* point)
{
	b2ContactPoint cp;
	cp.shape1 = point->shape1;
	cp.shape2 = point->shape2;
	cp.position = point->position;
	cp.normal = point->normal;
	cp.id = point->id;
	contactPoints[cp.id.key] = cp;
}

void CollisionManager::Remove(const b2ContactPoint* point)
{
	std::map<int, b2ContactPoint>::iterator it = contactPoints.find(point->id.key);
	if (it != contactPoints.end()) {
		contactPoints.erase(contactPoints.find(point->id.key));
	}
}

bool CollisionManager::isOnGround(b2Shape* shapeToTest) const
{
	std::pair<int, b2ContactPoint> item;
	foreach(item, contactPoints) {
		b2ContactPoint& point = item.second;
		if ((shapeToTest == point.shape1 && point.normal.y < 0) ||
			(shapeToTest == point.shape2 && point.normal.y > 0)) {
				return true;
		}
	}
	return false;
}

bool CollisionManager::isOnWall(b2Shape* shapeToTest) const
{
	std::pair<int, b2ContactPoint> item;
	foreach(item, contactPoints) {
		b2ContactPoint& point = item.second;
		if ((shapeToTest == point.shape1 || shapeToTest == point.shape2) && point.normal.x != 0) {
			return true;
		}
	}
	return false;
}
